package com.lhl.fw.db.config;

import com.lhl.fw.db.repository.BaseJpaRepositoryFactoryBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * @className: AppConfig
 * @description: TODO 类描述
 * @author: king
 * @date: 2020-09-03 17:16
 **/
@Configuration
@PropertySource("classpath:application.properties")
@EnableJpaRepositories(basePackages= {"com.lhl.fw.db.biz.repository"},
        repositoryFactoryBeanClass  = BaseJpaRepositoryFactoryBean.class)
@ComponentScan("com.lhl")
@Slf4j
public class AppConfig implements EnvironmentAware {

    private Environment environment;

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(environment.getRequiredProperty("spring.datasource.url"));
        dataSource.setUsername(environment.getRequiredProperty("spring.datasource.username"));
        dataSource.setPassword(environment.getRequiredProperty("spring.datasource.password"));
        log.debug("spring.datasource.driver-class-name=={}",
                environment.getRequiredProperty("spring.datasource.driver-class-name"));
        log.debug("spring.datasource.url=={}", environment.getRequiredProperty("spring.datasource.url"));
        log.debug("spring.datasource.username=={}", environment.getRequiredProperty("spring.datasource.username"));
        log.debug("spring.datasource.password", environment.getRequiredProperty("spring.datasource.password"));
        return dataSource;
    }

    @Bean
    @Autowired
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource ds) {
        final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(ds);
        final HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setDatabase(Database.MYSQL);
        adapter.setShowSql(true);
        adapter.setGenerateDdl(true);
        Properties jpaProperties = new Properties();
        jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");// validate,create,create-drop
        jpaProperties.setProperty("hibernate.format_sql", "true");
        jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        emf.setPackagesToScan("com.lhl.fw.db.biz.domain.entity");
        emf.setJpaVendorAdapter(adapter);
        emf.setJpaProperties(jpaProperties);
        return emf;
    }

    @Bean
    @Autowired
    public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf.getObject());
        return transactionManager;
    }

    @Bean
    public PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor() {
        PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor =
                new PersistenceAnnotationBeanPostProcessor();
        return persistenceAnnotationBeanPostProcessor;
    }
}
